{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Code：<a href=\"https://github.com/lotapp/BaseCode\" target=\"_blank\">https://github.com/lotapp/BaseCode</a>\n",
    "\n",
    "多图旧版：<a href=\"https://www.cnblogs.com/dunitian/p/9186561.html\" target=\"_blank\">https://www.cnblogs.com/dunitian/p/9186561.html</a>\n",
    "\n",
    "在线编程：<a href=\"https://mybinder.org/v2/gh/lotapp/BaseCode/master\" target=\"_blank\">https://mybinder.org/v2/gh/lotapp/BaseCode/master</a>\n",
    "\n",
    "在线预览：<a href=\"http://github.lesschina.com/python/base/pop/4.func.html\" target=\"_blank\">http://github.lesschina.com/python/base/pop/4.func.html</a>\n",
    "\n",
    "主要是普及一下Python基础语法，对比着Net，新手更容易上手。\n",
    "\n",
    "对比学习很有意思的，尤其是一些底层和思路\n",
    "\n",
    "本来感觉函数要说的地方没多少，细细一规划，发现～还是单独拉出一篇说说吧\n",
    "\n",
    "之后就进入面向对象了，函数还是有必要了解一下的，不然到时候Class里面的方法定义又要说了。\n",
    "\n",
    "演示的模式一直在变，刚开始让大家熟悉一下 **`VSCode`**，后来引入了 **`ipython3`**交互式编程的概念\n",
    "\n",
    "现在就用前几天讲的 **`Jupyter-Notebook`**来演示了（VSCode现在也有这个预览版的插件了）\n",
    "\n",
    "过几天我们会直接 **像写文章一般的Coding**，一边写文章一边Code，最后还能生成需要的页面\n",
    "\n",
    "## 1.Python函数定义\n",
    "\n",
    "\n",
    "### 1.1.定义一个无参函数\n",
    "\n",
    "定义一个空函数：（**不写pass就报错了**）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 空函数定义\n",
    "def method():\n",
    "    pass #相当于占位符，ifelse等等里面都是可以出现的\n",
    "\n",
    "method()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义一个无参函数\n",
    "def get_name():\n",
    "    print(\"我叫张三\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我叫张三\n"
     ]
    }
   ],
   "source": [
    "# 调用一个无参函数\n",
    "get_name()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2.定义一个含参函数\n",
    "\n",
    "扩：文档说明用\"\"\" 或者'''来定义，就是如下效果\n",
    "\n",
    "![图片](https://images2018.cnblogs.com/blog/1127869/201806/1127869-20180612181119542-825240438.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义一个含参数的函数（name和age都是形参）\n",
    "def show_infos(name,age):\n",
    "    \"\"\"打印name和age\"\"\"#函数文档说明\n",
    "    print(\"我叫\",name,\"我的年龄是\",age)#这种输出方式会自动以空格连接字符串"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我叫 李四 我的年龄是 22\n"
     ]
    }
   ],
   "source": [
    "# 调用一个含参数的函数\n",
    "show_infos(\"李四\",22)#实参"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义一个含默认参数(缺省参数)的函数（默认参数必须指向不变对象）\n",
    "# 比如你设置一个list，改变了内容，则下次调用时，默认参数(缺省参数)的内容就变了，不再是函数定义时的值了\n",
    "def default_param(name,age=23):\n",
    "    \"\"\"age默认为23\"\"\"\n",
    "    print(\"我叫\",name,\"我的年龄是\",age)#这种输出方式会自动以空格连接字符串"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我叫 张三 我的年龄是 23\n"
     ]
    }
   ],
   "source": [
    "# 调用一个默认参数(缺省参数)的函数\n",
    "default_param(\"张三\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.3.定义有返回值的函数\n",
    "\n",
    "来个案例解释一下：（多返回值只是一种假象，Python函数返回的仍然是单一值～元组）\n",
    "\n",
    "多返回参数也可以返回一个`list、dict`来实现类似效果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义有返回值的函数\n",
    "def div_have_return(a,b):\n",
    "    \"\"\"计算a+b，返回计算结果\"\"\"#函数文档说明\n",
    "    return a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "计算结果为 3\n"
     ]
    }
   ],
   "source": [
    "# 调用有返回值的函数\n",
    "result=div_have_return(1,2)\n",
    "print(\"计算结果为\",result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义含有多个返回值的函数（利用了元组）\n",
    "def div_have_returns(a,b):\n",
    "    \"\"\"计算a+b的和，计算a-b，并返回两个结果\"\"\"\n",
    "    return (a+b),(a-b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sum: 3 D-value: -1\n"
     ]
    }
   ],
   "source": [
    "# 调用含有多个返回值的函数\n",
    "sum,dvalue=div_have_returns(1,2)\n",
    "print(\"sum:\",sum,\"D-value:\",dvalue)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(3, -1)\n"
     ]
    }
   ],
   "source": [
    "# 测试一下～返回多个值其实是利用了元组\n",
    "# 多返回值只是一种假象，Python函数返回的仍然是单一值～元组\n",
    "test=div_have_returns(1,2)\n",
    "print(test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义函数时，需要确定函数名和参数个数\n",
    "# 如果有必要，可以先对参数的数据类型做检查\n",
    "# 函数体内部可以用return随时返回函数结果\n",
    "# 函数执行完毕也没有return语句时，自动return None\n",
    "# 函数可以同时返回多个值，但其实就是一个tuple"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 扩展：使用list实现\n",
    "# 定义含有多个返回值的函数（利用了元组）\n",
    "def div_have_returns(a,b):\n",
    "    \"\"\"计算a+b的和，计算a-b，并返回两个结果\"\"\"\n",
    "    return [a+b,a-b]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[3, -1]"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 调用含有多个返回值的函数\n",
    "div_have_returns(1,2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.Python函数传参系列\n",
    "\n",
    "### 2.1.引用传递（通过元组、列表实现）\n",
    "\n",
    "扩展有`可变类型`和`不可变类型`作为形参的对比"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "######## 通过元组、列表实现 ########\n",
    "def default_some_params(nums):\n",
    "    \"\"\"借助Tuple和list\"\"\"\n",
    "    sum=0\n",
    "    for item in nums:\n",
    "        sum+=item\n",
    "    return sum"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "15"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 元组传入\n",
    "default_some_params((1,2,3,4,5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "15"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 列表传入\n",
    "default_some_params(list(range(1,6)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2.可变参数\n",
    "\n",
    "定义一个可变参数的函数(参数名字一般都是`*args`)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "######## 定义一个可变参数的函数(名字一般都是*args) ########\n",
    "# 定义可变参数和定义一个list或tuple参数相比，仅仅在参数前面加了一个*号。\n",
    "# 在函数内部，接收到的参数是一个tuple。调用该函数时，可以传入任意个参数（包括0个参数）\n",
    "def default_params(*args):\n",
    "    \"\"\"定义一个可变参数,用来求所有参数的总和\"\"\"\n",
    "    sum=0\n",
    "    for item in args:\n",
    "        sum+=item\n",
    "    return sum"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "15"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 调用一个可变参数的函数\n",
    "default_params(1,2,3,4,5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "15"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 传一个list或者Tuple（参数前面加*）\n",
    "# 传一个元组\n",
    "test_tuple=(1,2,3,4,5)\n",
    "default_params(*test_tuple)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "15"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# range(1,6) ==> [1,6) ==> 1,2,3,4,5\n",
    "test_list=list(range(1,6))\n",
    "default_params(*test_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "来个**Main**传参的扩展，贴两张图即可：\n",
    "\n",
    "![图片](https://images2018.cnblogs.com/blog/1127869/201806/1127869-20180627095902529-413430440.png)\n",
    "![图片](https://images2018.cnblogs.com/blog/1127869/201806/1127869-20180627095928962-828764857.png)\n",
    "\n",
    "---\n",
    "\n",
    "### 2.3.关键字参数\n",
    "\n",
    "定义含关键字参数的函数：`def default_kv_params(name,age=23,**kv):`\n",
    "\n",
    "可变参数允许你传入0个或任意个参数，这些可变参数在函数调用时自动组装为一个`tuple`\n",
    "\n",
    "关键字参数允许你传入0个或任意个含`key-value`的参数，自动组装为一个`dict`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "######## 调用含关键字参数的函数 ########\n",
    "# 可变参数允许你传入0个或任意个参数，这些可变参数在函数调用时自动组装为一个tuple\n",
    "# 关键字参数允许你传入0个或任意个含key-value的参数，自动组装为一个dict\n",
    "def default_kv_params(name,age=23,**kv):\n",
    "    \"\"\"输出输出用户传参\"\"\"\n",
    "    print(\"我叫\",name,\"我的年龄是\",age,\"dict:\",kv)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我叫 dnt 我的年龄是 23 dict: {'web': 'www.baidu.com', 'qq': 110}\n"
     ]
    }
   ],
   "source": [
    "# 调用含关键字参数的函数\n",
    "default_kv_params(\"dnt\",web=\"www.baidu.com\",qq=110)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "来个 **综合案例**：`def default_god_params(name,age=23,*args,**kv):`\n",
    "\n",
    "需要注意py里面的书写格式 ==> **先定义再调用**（<a href=\"https://github.com/lotapp/BaseCode/blob/master/python/1.POP/4.func_IO/1.func_div.py\" target=\"_blank\">Code参考</a>）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "#### 同时定义可变参数+关键字参数 ####\n",
    "def default_god_params(name,age=23,*args,**kv):\n",
    "    \"\"\"同时有可变参数+关键字参数的使用方法\"\"\"\n",
    "    print(\"我叫\",name,\"我的年龄是\",age,\"list:\",args,\"dict:\",kv)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我叫 dnt 我的年龄是 24 list: (1, 2, 3, 4, 5) dict: {'web': 'www.baidu.com', 'qq': 110}\n"
     ]
    }
   ],
   "source": [
    "# 调用可变参数+关键字参数\n",
    "# 有名字给kv,没名字给args\n",
    "default_god_params(\"dnt\",24,1,2,3,4,5,web=\"www.baidu.com\",qq=110)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我叫 dnt 我的年龄是 24 list: (1, 2, 3, 4, 5) dict: {}\n"
     ]
    }
   ],
   "source": [
    "#只调用可变参数\n",
    "default_god_params(\"dnt\",24,1,2,3,4,5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我叫 dnt 我的年龄是 23 list: () dict: {'web': 'www.baidu.com', 'qq': 110}\n"
     ]
    }
   ],
   "source": [
    "# 只调用关键字参数\n",
    "default_god_params(\"dnt\",web=\"www.baidu.com\",qq=110)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我叫 1 我的年龄是 2 list: (3, 4, 5) dict: {'web': 'www.baidu.com', 'qq': 110}\n"
     ]
    }
   ],
   "source": [
    "#### 传元组和字典 ####\n",
    "test_tuple=(1,2,3,4,5)\n",
    "test_dict={\"web\":\"www.baidu.com\",\"qq\":110}\n",
    "\n",
    "default_god_params(*test_tuple,**test_dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.CSharp函数基础\n",
    "\n",
    "`C#`基础语法大家都很熟了，我贴一个注释的`Code`即可（<a href=\"https://github.com/lotapp/BaseCode/blob/master/netcore/1_POP/6func/Program.cs\" target=\"_blank\">Code在线</a>）\n",
    "\n",
    "`VSCode`里面如果也想像VS一样，`///`就生成注释 ==》请安装函数文档注释：**XML Documentation Comments**\n",
    "\n",
    "```csharp\n",
    "using System;\n",
    "using System.Collections.Generic;\n",
    "\n",
    "namespace _6func\n",
    "{\n",
    "    class Program\n",
    "    {\n",
    "        static void Main(string[] args)\n",
    "        {\n",
    "            // 交换两数新方式\n",
    "            int x = 3, y = 5;\n",
    "            (x, y) = (y, x);\n",
    "            System.Console.WriteLine(\"{0},{1}\", x, y);\n",
    "            \n",
    "            #region Base\n",
    "            // # 定义一个空函数：\n",
    "            Method();\n",
    "            // # 定义一个无参函数\n",
    "            GetName();\n",
    "            // # 定义一个含参函数\n",
    "            ShowInfos(\"李四\", 22);\n",
    "            // # 定义一个含默认参数(缺省参数)的函数\n",
    "            DefaultParam(\"张三\");\n",
    "            // # 定义有返回值的函数\n",
    "            int result = DivHaveReturn(1, 2);\n",
    "            Console.WriteLine($\"计算结果为{result}\");\n",
    "            #endregion\n",
    "\n",
    "            // # 定义含有多个返回值的函数（利用了元组）\n",
    "            var (sum, dvalue) = DivHaveReturns(1, 2);\n",
    "            Console.WriteLine($\"sum:{sum},D-value:{dvalue}\");\n",
    "\n",
    "            // 传多个参数系列：\n",
    "            // 引用传递（通过元组、列表实现）：扩展有可变类型和不可变类型作为形参的对比\n",
    "            var list = new List<int>() { 1, 2, 3, 4, 5 };\n",
    "            Console.WriteLine(DefaultSomeParams(list));\n",
    "            Console.WriteLine(list.Count);//这就是引用传递的证明\n",
    "\n",
    "            // # 定义一个可变参数的函数(参数名字一般都是*args)\n",
    "            Console.WriteLine(DefaultParams(1, 2, 3, 4, 5));\n",
    "\n",
    "            // # 定义含关键字参数的函数 直接传Dict\n",
    "        }\n",
    "\n",
    "        #region base\n",
    "        /// <summary>\n",
    "        /// 定义一个空函数\n",
    "        /// </summary>\n",
    "        private static void Method()\n",
    "        {\n",
    "\n",
    "        }\n",
    "        /// <summary>\n",
    "        /// 定义一个无参函数\n",
    "        /// </summary>\n",
    "        // private static void GetName()\n",
    "        // {\n",
    "        //     Console.WriteLine(\"你好\");\n",
    "        // }\n",
    "        //简写\n",
    "        private static void GetName() => Console.WriteLine(\"你好\");\n",
    "\n",
    "        /// <summary>\n",
    "        /// 定义一个含参数的函数\n",
    "        /// </summary>\n",
    "        /// <param name=\"name\">名字</param>\n",
    "        /// <param name=\"age\">年龄</param>\n",
    "        // private static void ShowInfos(string name, int age)\n",
    "        // {\n",
    "        //     Console.WriteLine($\"我叫{name} 我的年龄是{age}\");\n",
    "        // }\n",
    "        //简写\n",
    "        private static void ShowInfos(string name, int age) => Console.WriteLine($\"我叫{name} 我的年龄是{age}\");\n",
    "\n",
    "        /// <summary>\n",
    "        /// 定义一个含缺省参数的函数\n",
    "        /// </summary>\n",
    "        /// <param name=\"name\">名字</param>\n",
    "        /// <param name=\"age\">年龄默认23</param>\n",
    "        // private static void DefaultParam(string name, int age = 23)\n",
    "        // {\n",
    "        //     Console.WriteLine($\"我叫{name} 我的年龄是{age}\");\n",
    "        // }\n",
    "        //简写\n",
    "        private static void DefaultParam(string name, int age = 23) => Console.WriteLine($\"我叫{name} 我的年龄是{age}\");\n",
    "\n",
    "        /// <summary>\n",
    "        /// 定义一个有返回值的函数（计算a+b，返回计算结果）\n",
    "        /// </summary>\n",
    "        /// <param name=\"a\">num1</param>\n",
    "        /// <param name=\"b\">num2</param>\n",
    "        // private static int DivHaveReturn(int a, int b)\n",
    "        // {\n",
    "        //     return a + b;\n",
    "        // }\n",
    "        //简写\n",
    "        private static int DivHaveReturn(int a, int b) => a + b;\n",
    "        #endregion\n",
    "\n",
    "        /// <summary>\n",
    "        /// 定义含有多个返回值的函数（利用了元组）\n",
    "        /// 计算a+b的和，计算a-b，并返回两个结果\n",
    "        /// </summary>\n",
    "        /// <param name=\"a\"></param>\n",
    "        /// <param name=\"b\"></param>\n",
    "        /// <returns></returns>\n",
    "        // private static (int sum,int dValue) DivHaveReturns(int a, int b)\n",
    "        // {\n",
    "        //     return ((a+b),(a-b));\n",
    "        // }\n",
    "        //简写\n",
    "        private static (int sum, int dValue) DivHaveReturns(int a, int b) => ((a + b), (a - b));\n",
    "\n",
    "        #region 传入多个参数系列\n",
    "        /// <summary>\n",
    "        /// 利用列表实现,引用传递之类的C#还有ref和out，这边就不说了\n",
    "        /// </summary>\n",
    "        /// <param name=\"nums\"></param>\n",
    "        /// <returns></returns>\n",
    "        private static int DefaultSomeParams(List<int> numList)\n",
    "        {\n",
    "            int sum = 0;\n",
    "            foreach (var item in numList)\n",
    "            {\n",
    "                sum += item;\n",
    "            }\n",
    "            numList.Clear();\n",
    "            return sum;\n",
    "        }\n",
    "        /// <summary>\n",
    "        /// 定义一个可变参数的函数\n",
    "        /// </summary>\n",
    "        /// <param name=\"args\"></param>\n",
    "        /// <returns></returns>\n",
    "        private static int DefaultParams(params int[] args)\n",
    "        {\n",
    "            int sum = 0;\n",
    "            foreach (var item in args)\n",
    "            {\n",
    "                sum += item;\n",
    "            }\n",
    "            return sum;\n",
    "        }\n",
    "        #endregion\n",
    "    }\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4.函数扩展\n",
    "\n",
    "### 4.1.Python递归函数\n",
    "\n",
    "函数递归调用其实就是自己调用自己，**关键点只要考虑什么时候跳出即可**(没有跳出就是死循环)\n",
    "\n",
    "先来个简单的案例熟悉一下:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 函数递归调用其实就是自己调用自己，关键点只要考虑什么时候跳出即可(没有跳出就是死循环)\n",
    "# 阶乘案例 n!\n",
    "def factorial(n):\n",
    "    if n==1:\n",
    "        return n #跳出\n",
    "    elif n>1:\n",
    "        return n*factorial(n-1) #规律公式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "24\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "print(factorial(4))\n",
    "print(factorial(-4))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "来个案例(实际工作中并不会自己定义,用系统自带<a href=\"https://www.cnblogs.com/dotnetcrazy/p/9114691.html#3.8.Python格式系列\" target=\"_blank\">strip</a>方法即可)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 利用切片操作，实现一个trim()函数，去除字符串首尾的空格\n",
    "# 跳出点==> 第一个字符和最后一个字符不是空格\n",
    "def my_trim(input_str):\n",
    "    if input_str[0] != \" \" and input_str[-1] != \" \":\n",
    "        return input_str\n",
    "    elif input_str[0]==\" \":\n",
    "        return my_trim(input_str[1:])#从第二个到最后一个字符\n",
    "    elif input_str[-1]==\" \":\n",
    "        return my_trim(input_str[:-1])#从第一个到倒数第二个(end_index取不到)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我去\n",
      "我去\n",
      "我去\n"
     ]
    }
   ],
   "source": [
    "print(my_trim(\"我去  \"))\n",
    "print(my_trim(\"  我去\"))\n",
    "print(my_trim(\"  我去  \"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.2.CSharp递归\n",
    "\n",
    "C#的递归我就引用一下以前的（<a href=\"https://github.com/dunitian/LoTCodeBase/blob/master/NetCode/1.面向过程/01.基础/10.递归案例/Program.cs\" target=\"_blank\">Code</a>）\n",
    "\n",
    "```csharp\n",
    "using System;\n",
    "\n",
    "namespace _10.递归案例\n",
    "{\n",
    "    class Program\n",
    "    {\n",
    "        //一列数的规则如下: 1、1、2、3、5、8、13、21、34...... 求第30位数是多少， 用递归算法实现\n",
    "        static void Main(string[] args)\n",
    "        {\n",
    "            //1     2       3       4       5           n\n",
    "            //1     1      1+1     2+1     3+2   Fn(n-2)+Fn(n-1)\n",
    "            Console.WriteLine(GetNum(30));\n",
    "            Console.ReadKey();\n",
    "        }\n",
    "        /// <summary>\n",
    "        /// 递归就这么理解，先找能打破重复的条件，然后就不断的重复去吧\n",
    "        /// </summary>\n",
    "        /// <param name=\"n\"></param>\n",
    "        /// <returns></returns>\n",
    "        private static int GetNum(int n)\n",
    "        {\n",
    "            if (n == 1 || n == 2)\n",
    "            {\n",
    "                return 1;\n",
    "            }\n",
    "            else\n",
    "            {\n",
    "                return GetNum(n - 1) + GetNum(n - 2);\n",
    "            }\n",
    "\n",
    "        }\n",
    "    }\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.3.匿名函数\n",
    "\n",
    "C#上面Code中的简写都是用匿名函数的方式，可以参考。\n",
    "\n",
    "这边说说Python的匿名函数，这就没有C#优美了，先看看公式：`lambda 参数: 表达式` \n",
    "\n",
    "看个简单案例实践一下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Python对匿名函数的支持有限，只有一些简单的情况下可以使用匿名函数\n",
    "# lambda 参数: 表达式\n",
    "# 来个简单求和案例:\n",
    "sum=lambda a,b: a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sum(1,2) #调用一下看看(有点js的感觉,函数可以直接赋值给变量,然后直接用)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "来个经常用的排序案例：`data_list.sort(key=lambda x:x[\"key\"])`\n",
    "\n",
    "还有一个比较常用的地方 == > **当参数传递** `def sum(a,b,func):` `sum(1,2,lambda x,y: x+y)`\n",
    "\n",
    "先看案例："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 来个实际案例,还记得list的排序吗?\n",
    "# 这次按照指定key排序(有点 SQL 里面 order by 的感觉)\n",
    "data_list=[\n",
    "    {\"name\":\"a张三\",\"age\":21},\n",
    "    {\"name\":\"b李四\",\"age\":23},\n",
    "    {\"name\":\"a王五\",\"age\":22}]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[{'name': 'a张三', 'age': 21}, {'name': 'a王五', 'age': 22}, {'name': 'b李四', 'age': 23}]\n",
      "[{'name': 'a张三', 'age': 21}, {'name': 'a王五', 'age': 22}, {'name': 'b李四', 'age': 23}]\n"
     ]
    }
   ],
   "source": [
    "# 按照age排序\n",
    "data_list.sort(key=lambda x:x[\"age\"])\n",
    "print(data_list)\n",
    "\n",
    "# 按照name排序\n",
    "data_list.sort(key=lambda x:x[\"name\"])\n",
    "print(data_list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on built-in function sort:\n",
      "\n",
      "sort(...) method of builtins.list instance\n",
      "    L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE*\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# 可以看看帮助文档\n",
    "help(data_list.sort)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 当函数的参数传递(有时候需要传一个匿名方法去函数中处理某些事情)\n",
    "def sum(a,b,func):\n",
    "   return func(a,b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sum(1,2,lambda x,y: x+y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.4.全局变量和局部变量\n",
    "\n",
    "有人可能会说，这个就太简单了，没啥好说的，(⊙o⊙)… `Python`还真需要说说，来个案例给你猜结果："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 有人可能会说，这个就太简单了，没啥好说的，(⊙o⊙)… Python还真需要说说\n",
    "a=100\n",
    "b=[1,2]\n",
    "\n",
    "def set_num(num):\n",
    "    num+=num\n",
    "\n",
    "set_num(a)\n",
    "set_num(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "100\n",
      "[1, 2, 1, 2]\n"
     ]
    }
   ],
   "source": [
    "# 发现全局变量a木有被修改，而b修改了\n",
    "print(a)\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "直接看结果吧：发现全局变量a木有被修改，而b修改了？\n",
    "\n",
    "啥情况呢？来个简单案例说明下吧～"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "100\n"
     ]
    }
   ],
   "source": [
    "# 还是来个简单案例说明下吧～\n",
    "a=100\n",
    "\n",
    "def set_num(num):\n",
    "    a=200\n",
    "\n",
    "set_num(a)\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这是因为，`python`定义一个变量的写法不用加类型导致的`(⊙﹏⊙) `\n",
    "\n",
    "所以函数里面`a=200`，python解释器就认为 **你定义了一个和a这个全局变量名字相同的局部变量**\n",
    "\n",
    "那怎么用呢？`global`来声明一下全局变量即可："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "200\n"
     ]
    }
   ],
   "source": [
    "# a=200，python解释器就认为你定义了一个和a这个全局变量名字相同的局部变量，那怎么用呢？global来声明一下即可\n",
    "a=100\n",
    "\n",
    "def set_num(num):\n",
    "    global a\n",
    "    a=200\n",
    "\n",
    "set_num(a)\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**总结**：\n",
    "\n",
    "在函数中不使用`global`声明全局变量不能修改全局变量 ==> 本质是不能修改全局变量的指向，即 **不能将全局变量指向新的数据**\n",
    "\n",
    "对于 **不可变类型**的全局变量来说，因其 **指向的数据不能修改**，所以不使用`global`时无法修改全局变量\n",
    "\n",
    "对于 **可变类型**的全局变量来说，因其 **指向的数据可以修改**，所以不使用`global`时也可修改全局变量\n",
    "\n",
    "### 4.5.可变类型和不可变类型\n",
    "\n",
    "有人可能会问了，之前<a href=\"https://www.cnblogs.com/dotnetcrazy/p/9102030.html#8.3.Python扩展（++---）\" target=\"_blank\">基础部分自增自减</a>说了一下：\n",
    "\n",
    "**`Python分为：可变类型：list，dict,set等等 和 不可变类型：int，str，tuple，float等等`**\n",
    "\n",
    "后来<a href=\"https://www.cnblogs.com/dotnetcrazy/p/9155310.html#5.2.增加和修改\" target=\"_blank\">Dict添加修改</a>又提了一下，还没太清楚怎么办？\n",
    "\n",
    "不用慌，今天统统解决，先来个案例看看怎么个`可变和不可变`吧："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "a=\"mmd\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'m'"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'str' object does not support item assignment",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-3-f2c76b4f2b09>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0;31m# 没法修改\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0ma\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'd'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m: 'str' object does not support item assignment"
     ]
    }
   ],
   "source": [
    "# 没法修改\n",
    "a[0]='d'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'m'"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a=['m','m','d']\n",
    "a[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['n', 'm', 'd']"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[0]='n'\n",
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这个直观吧，先这样理解 ==> **可变就是可修改，不可变就是不可修改**\n",
    "\n",
    "其实有个小技巧：**`看可变不可变就看修改前和修改后的id是否相同，不同就是不可变，相同则是可变`**\n",
    "\n",
    "在C#或者其他语言里面int是可以修改的，可能对Python的`int是不可变类型`有所怀疑，所以我们验证一下"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "94490537630240"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "i=1\n",
    "id(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "94490537630272"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 地址改变了\n",
    "i+=1\n",
    "id(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "94490537630304"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 地址又变了\n",
    "i=i+1\n",
    "id(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到执行 `i+=1` 时，内存地址都会变化，更加证实了int类型是**不可变类型**\n",
    "\n",
    "再来个案例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "94490537630240"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "j=1\n",
    "id(j) # 有没有发现，跟一开始i的内存地址一样了"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对于不可变类型`int`，无论创建多少个不可变类型，只要值相同，都指向同个内存地址"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 更直观的来几个案例\n",
    "a=1\n",
    "b=1\n",
    "c=1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "94490537630240\n",
      "94490537630240\n",
      "94490537630240\n"
     ]
    }
   ],
   "source": [
    "# 不仅仅都一样，还和所有等于1的变量地址都相同\n",
    "# 这下不怀疑了吧\n",
    "print(id(a))\n",
    "print(id(b))\n",
    "print(id(c))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "不怀疑后，再来个拓展 ～ `float是否一样呢` ？\n",
    "\n",
    "来个案例看看"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "139755722935032"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f1=1.2\n",
    "id(f1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "139755722934936"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 地址变了，说明float也是不可变类型\n",
    "f1+=1.0\n",
    "id(f1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "但是下面部分就和int不一样咯～\n",
    "\n",
    "声明两个**相同值**的浮点型变量，查看它们的id，发现它们并不是指向同个内存地址(**这点和int类型不同**)\n",
    "\n",
    "这方面涉及Python内存管理机制，Python对int类型和较短的字符串进行了缓存，无论声明多少个值相同的变量，实际上都指向同个内存地址\n",
    "\n",
    "总之知道`float`也是不可变类型即可"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "139755722935224\n",
      "139755722935128\n"
     ]
    }
   ],
   "source": [
    "f2=1.2\n",
    "f3=1.2\n",
    "print(id(f2))\n",
    "print(id(f3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "不可变看完了,来看看**可变类型**："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "139755687637576"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list1=[12,11,1]\n",
    "id(list1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "139755687637576"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 改完还是自己原来的地址～说明是可变类型\n",
    "list1.append(0)\n",
    "id(list1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "下面验证一下：当存在多个值相同的不可变类型变量时，看看它们是不是跟可变类型一样指向同个内存地址：\n",
    "\n",
    "结论：**当存在多个值相同的不可变类型变量时，并不是指向同一个地址**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "139755687065160\n",
      "139755687093704\n"
     ]
    }
   ],
   "source": [
    "# 当存在多个值相同的不可变类型变量时，并不是指向同一个地址\n",
    "list2=[12,11,1]\n",
    "list3=[12,11,1]\n",
    "print(id(list2))\n",
    "print(id(list3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "老规矩，来个扩展：\n",
    "\n",
    "想同一个地址怎么办？直接赋值即可（注意下面的一种情况）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "139755687065160\n",
      "139755687093704\n",
      "139755687065160\n"
     ]
    }
   ],
   "source": [
    "print(id(list2))\n",
    "print(id(list3))\n",
    "list3=list2\n",
    "print(id(list3)) # 现在list3的地址和list2地址一样了"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[12, 11, 1, 0]\n",
      "[12, 11, 1, 0]\n",
      "139755687065160\n",
      "139755687065160\n"
     ]
    }
   ],
   "source": [
    "# 注意这种情况，如果对其中一个list修改，那么另一个也就跟着被修改了\n",
    "# 任意一个List进行修改，都会影响另外一个List的值\n",
    "list2.append(0)\n",
    "print(list2)\n",
    "print(list3)\n",
    "print(id(list2))\n",
    "print(id(list3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "关于可变类型和不可变类型今天就到这吧，下次还会再说更高深的知识点的，尽请期待哦～\n",
    "\n",
    "---\n",
    "\n",
    "### 4.6.验证扩展系列\n",
    "\n",
    "下面就进入验证扩展系列，看看一些概念：\n",
    "\n",
    "1.之前很多资料说**python3的匿名函数里不能调用print函数**,自己测试下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 之前很多资料说py3匿名函数里不能调用print函数,自己测试下\n",
    "# 定义一个无参匿名函数\n",
    "printf=lambda:print(\"I Love You\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "I Love You\n"
     ]
    }
   ],
   "source": [
    "printf()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2.**可变类型与不可变类型的变量分别作为函数参数的区别**\n",
    "\n",
    "感到疑惑可以看之前的运算符扩展（<a href=\"https://www.cnblogs.com/dunitian/p/9186561.html#ext\" target=\"_blank\">点我</a>）\n",
    "\n",
    "上面讲完可变和不可变再看这个就太轻松了～\n",
    "\n",
    "`Python中函数参数都是引用传递`\n",
    "\n",
    "对于不可变类型，**因变量不能修改，所以运算不会影响到变量自身**\n",
    "\n",
    "而对于可变类型来说，**函数体中的运算有可能会更改传入的参数变量**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 可变类型与不可变类型的变量分别作为函数参数的区别\n",
    "def default_some_params(nums):\n",
    "    nums+=nums"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_num=1\n",
    "default_some_params(test_num)\n",
    "test_num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4, 5, 1, 2, 3, 4, 5]"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_list=list(range(1,6))\n",
    "default_some_params(test_list)\n",
    "test_list"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3.**函数名能不能重复的问题**\n",
    "\n",
    "在C#或者Java之中，能不能重载:**`具有不同的参数的类型或参数的个数【跟返回值没关系】`**\n",
    "\n",
    "结论：**函数名不能重名**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 函数名能不能重复的问题（能不能重载：具有不同的参数的类型或参数的个数）\n",
    "def test():\n",
    "    pass\n",
    "\n",
    "def test(a,b):\n",
    "    return a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test(1,2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "test() missing 2 required positional arguments: 'a' and 'b'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-29-023d21616394>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mtest\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m#前一个直接被后一个覆盖掉了\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m: test() missing 2 required positional arguments: 'a' and 'b'"
     ]
    }
   ],
   "source": [
    "test() #前一个直接被后一个覆盖掉了"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "4.**这次说说两个有趣的扩展**\n",
    "\n",
    "交换两数这个<a href=\"https://www.cnblogs.com/dotnetcrazy/p/9155310.html#3.2.拆包、多维元组\" target=\"_blank\">之前就说过了</a>，这边再提一下：\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "1\n"
     ]
    }
   ],
   "source": [
    "# 交换两数～元组的方式\n",
    "a=1\n",
    "b=2\n",
    "a,b=b,a # 写全：(a,b)=(b,a)\n",
    "print(a)\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "C#的再<a href=\"https://www.cnblogs.com/dotnetcrazy/p/9155310.html#4.CSharp元组相关\" target=\"_blank\">回顾一下</a>：\n",
    "```csharp\n",
    "int x = 1, y = 2;\n",
    "(x, y) = (y, x);\n",
    "Console.WriteLine(\"x： \" + x + \"  y： \" + x);\n",
    "```\n",
    "\n",
    "---\n",
    "\n",
    "5.**`eval`**（和js里面的eval差不多）：不太建议使用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "请输入：print(\"厉害\")\n",
      "print(\"厉害\")\n",
      "厉害\n"
     ]
    }
   ],
   "source": [
    "# 2.eval（和js里面的eval差不多）：\n",
    "input_str=input(\"请输入：\")\n",
    "print(input_str)\n",
    "eval(input_str)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
